/**
 * FunctionSequencer
 *
 * @author		Allen Chou
 * @version		1.0.0 (last update: Feb 12 2008)
 * @link		http://cjcat2266.deviantart.com
 */

package idv.cjcat.utils {
	import flash.errors.IllegalOperationError;
	
	public class FunctionSequencer {
		
		public var locked:Boolean = false;
		
		private var _functionSequence:Array;
		private var _stepper:StepInt;
		private var _first:Boolean = true;
		
		/**
		 * @param	functionSequence  The Array of Functions that would be called sequentially by the FunctionSequencer
		 */
		public function FunctionSequencer(functionSequence:Array) {
			for each (var func:* in functionSequence) {
				if (!(func is Function)) throw new IllegalOperationError("functionSequence can only contain Functions as elements.");
			}
			_functionSequence = functionSequence;
			_stepper = new StepInt(0, 0, _functionSequence.length);
		}
		
		//updated in ver 1.0.0 (use _first:Boolean for first-use calibration)
		/**
		 * Call the function to be called.
		 * @param	forward  Whether the pointer goes forward to the next fucntion or backward to the previous function.
		 */
		public function execute(forward:Boolean = true):void {
			if (locked) return;
			if (_first) {
				if (forward) {
					(_functionSequence[_stepper.getValue()]).apply();
				} else {
					_stepper.step(-1);
					(_functionSequence[_stepper.getValue()]).apply();
				}
				_first = false;
				return;
			}
			
			if (forward) {
					_stepper.step();
					(_functionSequence[_stepper.getValue()]).apply();
				
			} else {
					_stepper.step(-1);
					(_functionSequence[_stepper.getValue()]).apply();
				
			}
		}
		
		/**
		 * The index of the function in functionSequence to be executed
		 */
		public function get position():int {
			return _stepper.getValue();
		}
		
		/**
		 * The value parameter would be moduled to fit the functionSequence array
		 */
		public function set position(value:int):void {
			_stepper.setValue(value);
		}
		
		/**
		 * Array of all functions in the sequence.
		 */
		public function get functionSequence():Array {
			return _functionSequence;
		}
		
		public function set functionSequence(value:Array):void {
			_functionSequence = value;
			for each (var func:* in _functionSequence) {
				if (!(func is Function)) throw new IllegalOperationError("functionSequence can only contain Functions as elements.");
			}
		}
		
	}
	
}